/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - graphics/buffers
// Copyright( c) 2015.  All Rights Reserved
//
// File:		AEGpuResource.cpp
// Author:		Gianluca Belardelli
// Date:		19/12/2014
//
/////////////////////////////////////////////////////////////////////////
#include <AEEngine.h>

AEGpuResource::AEGpuResource( AEResourceManager *lpParentManager, AEUINT32 uiSize,	AEUINT32 uiUsageFlags, 	AEUINT32 uiBindFlags,
							 AEBOOL32 bHasSysmemCopy, AEBOOL32 bSafeCleanUp, const char *lpInternalName ) : AEResource( lpParentManager ),
							 m_uiSize( uiSize ),
							 m_uiUsageFlags( uiUsageFlags ),
							 m_uiBindFlags( uiBindFlags ),
							 m_bHasSysmemCopy( bHasSysmemCopy ),
							 m_bSafeCleanUp( bSafeCleanUp )
{
#if defined AE_OPENGL || AE_OPENGLES2

	AEASSERT_MSG( ( uiUsageFlags >= AEMEMUSAGE_STATIC && uiUsageFlags <= AEMEMUSAGE_STATIC_UNMANAGED ),
					"AEGpuResource::AEGpuResource Valore di uiUsageFlags non supportato per piattaforma OpenGL."
				);

	AEASSERT_MSG( ( uiBindFlags >= AEBIND_INDEX_BUFFER && uiBindFlags <= AEBIND_VERTEX_BUFFER ),
					"AEGpuResource::AEGpuResource Valore di uiBindFlags non supportato per piattaforma OpenGL."
				);

#endif

	m_lpSystemCopy = AENULL;
	m_lpLockedPtr = AENULL;
	m_uiLockFlags = AELOCKFLAG_NONE;
	m_uiLockedOffset = 0;
	m_uiLockedSize = 0;
	SetFilename( lpInternalName );

	_initResourcePlatformSpecific();
}

AEGpuResource::~AEGpuResource( void )
{
	_deinitResourcePlatformSpecific();

//	if( m_lpSystemCopy != AENULL )
//		AEngine::GetMemManager()->GetHeapAllocator().BlockFree( m_lpSystemCopy, m_uiSize );
}

AEBOOL32 AEGpuResource::Reload( void )
{
	if( m_lpSystemCopy == AENULL )
		return AEFALSE;

	FillWithData( m_lpSystemCopy, 0, m_uiSize, AELOCKFLAG_REPLACE_ALL );

	return AETRUE;
}

AEBOOL32 AEGpuResource::Unload( void )
{
	return AEFALSE;
}

AEBOOL32 AEGpuResource::CanBeLockedForReading( void ) const
{
	return AEFALSE;
}

// OpenGL ES2.0 non supporta il Lock sui buffer.
#ifndef AE_OPENGLES2
void AEGpuResource::FillWithData( const void *lpSourceData, AEUINT32 uiOffset, AEUINT32 uiSize, AEUINT32 uiLockFlags )
{
	AEASSERT_MSG( uiOffset < uiSize, "AEGpuResource::FillWithData uiOffset maggiore di uiSize." );
	AEASSERT_MSG( uiOffset + uiSize < m_uiSize, "AEGpuResource::FillWithData spazio nel buffer non sufficente." );
	AEASSERT_MSG( lpSourceData, "AEGpuResource::FillWithData lpSourceData non valido." );
	
	m_lpLockedPtr = Lock( uiLockFlags, uiOffset, uiSize );
	if( m_lpLockedPtr )
	{
		memcpy( m_lpLockedPtr, lpSourceData, uiSize );
		Unlock();

		if( m_bHasSysmemCopy )
		{
//			if( m_lpSystemCopy )
//				AEngine::GetMemManager()->GetHeapAllocator().BlockFree( m_lpSystemCopy, m_uiSize );

//			m_lpSystemCopy = AEngine::GetMemManager()->GetHeapAllocator().BlockAlloc( m_uiSize );
			memcpy( m_lpSystemCopy, lpSourceData, m_uiSize );
		}
	}
}
#endif // AE_OPENGLES2
